home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Floppyshop 2
/
Floppyshop - 2.zip
/
Floppyshop - 2.iso
/
art&graf.ix
/
art-3139
/
stadconv
/
tostad.asm
< prev
next >
Wrap
Assembly Source File
|
1987-04-21
|
16KB
|
292 lines
*****************************************************************************
* *
* Ass-Unterroutine zum Konvertieren eines 32k grossen Bildes (Screenformat) *
* in ein gepacktes STAD-Format. *
* *
* Aufruf: (sp) LONG Rücksprungadresse *
* 4(sp) LONG Adresse des Originalbildes (32k Buffer) *
* 8(sp) LONG Adresse des gepacktes STAD-Bildes (33k Buffer) *
* Rückgabe: d0 WORD Länge des gepackten STAD-Bildes *
* *
* History: *
* Version 1.0 01.06.1991 Wolfgang Ley *
* - Urversion *
* Version 1.1 03.06.1991 Wolfgang Ley *
* - Rettung der Register eingeführt *
* - Auswertung der Statistik verbessert *
* - kein zusätzlicher Statistik-Buffer mehr *
* Version 1.2 05.06.1991 Wolfgang Ley *
* - Statistikauswertung wieder rueckgaengig gem. *
* - zusätzliche Zaehler aus v_pack eliminiert *
* *
*****************************************************************************
TEXT
movem.l D1-A1,-(SP) ;Registerinhalte retten
movea.l 40(SP),A0 ;Adresse des 32k-Bildes
movea.l 44(SP),A1 ;Adresse des gepackten STAD-Bildes
;----------------------------------------------------------------------------
; Statistik aufstellen (welches Byte wird am häufgsten/wenigsten/zweitwenigsten
; benutzt) --> Wahl von PACK-/ID-/SPECIAL-Byte
;----------------------------------------------------------------------------
move.w #511,D0 ;Index-Register
stat_1: clr.b 0(A1,D0.w) ;Anzahlen löschen
dbra D0,stat_1
move.w #31999,D0 ;Zeiger innerhalb des Bildes
stat_2: move.b 0(A0,D0.w),D1 ;Byte holen
add.w D1,D1 ;verdoppeln
andi.w #$01FF,D1 ;Rest löschen
addq.w #1,0(A1,D1.w) ;und Byte zaehlen
dbra D0,stat_2 ;weiter gehts...
move.w #510,D0 ;bisher meist benutztes Byte
move.w 0(A1,D0.w),D1 ;Anzahl holen
move.w #508,D2 ;Rest-Zaehler
stat_3: cmp.w 0(A1,D2.w),D1 ;vergleichen
bhs.s stat_4
move.w D2,D0 ;Stelle merken
move.w 0(A1,D2.w),D1 ;und Anzahl merken
stat_4: subq.w #2,D2 ;naechster Eintrag
bpl.s stat_3 ;und weiter...
lsr.w #1,D0 ;nun haben wir das PACK-Byte
move.b D0,D3 ;PACK-Byte in D3
move.w #510,D0 ;bisher wenig-benutztes Byte
move.w 0(A1,D0.w),D1 ;Anzahl holen
move.w #508,D2 ;Rest-Zaehler
stat_5: cmp.w 0(A1,D2.w),D1 ;vergleichen
blo.s stat_6
move.w D2,D0 ;Stelle merken
move.w 0(A1,D2.w),D1 ;Anzahl merken
stat_6: subq.w #2,D2 ;naechste Anzahl
bpl.s stat_5 ;und weiter...
move.w #32001,0(A1,D0.w) ;Eintrag "löschen"
lsr.w #1,D0 ;nun haben wir das ID-Byte
move.b D0,D4 ;ID-Byte in D4
move.w #510,D0 ;bisher 2-wenigst benutztes Byte
move.w 0(A1,D0.w),D1
move.w #508,D2 ;s.o.
stat_7: cmp.w 0(A1,D2.w),D1
blo.s stat_8
move.w D2,D0
move.w 0(A1,D2.w),D1
stat_8: subq.w #2,D2
bpl.s stat_7
lsr.w #1,D0 ;nun haben wir das SPEC-Byte
move.b D0,D5 ;SPEC-Byte in D5
;----------------------------------------------------------------------------
; Horizontal+vertikal Packen, kleineres als STAD-Format übernehmen
; (dabei muss noch gecheckt werden, ob das gepackte Bild nicht länger geworden
; ist - in dem Fall als ungepacktes Bild übernehmen)
;----------------------------------------------------------------------------
bsr.s h_pack ;horizontal packen
move.w D0,D7 ;Länge (horiz.) merken
bsr v_pack ;vertikal packen
cmp.w D7,D0 ;vertikal kleiner?
bls.s check ;ja->alles klaro
bsr.s h_pack ;nein->nochmal horizontal packen
check: cmpi.w #32000,D0 ;ist das gepackte Bild wirklich
blo.s exit ;kleiner?
move.w #31999,D0 ;sonst Original 32k-Bild
copy: move.b (A0)+,(A1)+ ;kopieren
dbra D0,copy
move.w #32000,D0 ;als Läange 32000 Bytes angeben
exit: movem.l (SP)+,D1-A1 ;Register wieder herstellen
rts ;und das war's
;----------------------------------------------------------------------------
; horizontales Packen
;----------------------------------------------------------------------------
h_pack: move.b #'p',0(A1,D0.w) ;Header schreiben #'pM85'
move.b #'M',1(A1,D0.w) ;(als Bytes, falls Adresse ungerade)
move.b #'8',2(A1,D0.w)
move.b #'5',3(A1,D0.w)
move.b D4,4(A1,D0.w) ;ID-Byte schreiben
move.b D3,5(A1,D0.w) ;PACK-Byte schreiben
move.b D5,6(A1,D0.w) ;SPEC-Byte schreiben
moveq #7,D0 ;Headerlänge
clr.w D1 ;Offset für das Original
h_lese: move.b 0(A0,D1.w),D2 ;Byte holen
cmp.b D2,D4 ;ID-Byte gelesen?
beq.s h_use_spec
cmp.b D2,D5 ;SPEC-Byte gelesen?
beq.s h_use_spec
cmpi.w #31997,D1 ;kommen noch 2 weitere Bytes?
bhi.s h_as_is ;nein -> einzelne Bytes "as is"
cmp.b 1(A0,D1.w),D2 ;nochmal gleiches Byte?
bne.s h_as_is ;nein -> einzelnes Byte
cmp.b 2(A0,D1.w),D2 ;nochmal gleiches Byte?
bne.s h_as_is ;nein -> lohnt noch nicht (2 Bytes)
cmp.b D2,D3 ;PACK-Byte mehrmals?
beq.s h_use_pack ;ja, also ID-Byte nutzen
bra.s h_use_spec ;nein, also SPEC-Byte nutzen
h_as_is: move.b D2,0(A1,D0.w) ;Byte "as is" speichern
addq.w #1,D0 ;Offset weitersetzen
addq.w #1,D1 ;zum naechsten Byte gehen
h_weiter: cmpi.w #32000,D1 ;schon alles?
blo.s h_lese ;weiter packen..
rts ;sonst fertig
;----------------------------------------------------------------------------
; PACK-Byte-Kompression benutzen (horizontal)
;----------------------------------------------------------------------------
h_use_pack: clr.b D2 ;Anzahl Pack-Byte
addq.w #1,D1 ;Original-Bild weiterzaehlen
h_pack_1: cmpi.w #32000,D1 ;schon am Ende?
beq.s h_pack_fini
cmp.b 0(A0,D1.w),D3 ;immer noch PACK-Byte?
bne.s h_pack_fini
addq.b #1,D2 ;Anzahl Pack-Byte erhöhen
addq.w #1,D1 ;Original-Bild weiter
cmpi.b #255,D2 ;Anzahl-max erreicht?
bne.s h_pack_1 ;nein, also weiter auswerten
h_pack_fini: move.b D4,0(A1,D0.w) ;ID-Byte schreiben
move.b D2,1(A1,D0.w) ;und Anzahl Pack-Byte schreiben
addq.w #2,D0 ;zwei Byte geschrieben...
bra.s h_weiter ;und weiter lesen...
;----------------------------------------------------------------------------
; SPEC-Byte-Kompression benutzen (horizontal)
;----------------------------------------------------------------------------
h_use_spec: clr.b D6 ;Anzahl SPEC-Byte
addq.w #1,D1 ;Original-Bild weiterzählen
h_spec_1: cmpi.w #32000,D1 ;Schon fertig?
beq.s h_spec_fini
cmp.b 0(A0,D1.w),D2 ;immer noch Byte d?
bne.s h_spec_fini
addq.b #1,D6 ;Anzahl SPEC-Byte erhöhen
addq.w #1,D1 ;Original-Bild weiter
cmpi.b #255,D6 ;max-Anzahl erreicht?
bne.s h_spec_1 ;nein, also weiter...
h_spec_fini: move.b D5,0(A1,D0.w) ;SPEC-Byte schreiben
move.b D2,1(A1,D0.w) ;Byte d schreiben
move.b D6,2(A1,D0.w) ;Anzahl schreiben
addq.w #3,D0 ;drei Bytes geschrieben
bra.s h_weiter
;----------------------------------------------------------------------------
; vertikales Packen
;----------------------------------------------------------------------------
v_pack: moveq #0,D0 ;Länge des gepackten Bildes
clr.w D1 ;Original-Offset
move.b #'p',0(A1,D0.w) ;Header = #'pM86'
move.b #'M',1(A1,D0.w)
move.b #'8',2(A1,D0.w)
move.b #'6',3(A1,D0.w)
move.b D4,4(A1,D0.w) ;(siehe h_pack)
move.b D3,5(A1,D0.w)
move.b D5,6(A1,D0.w)
move.w #7,D0
v_lese: move.b 0(A0,D1.w),D2 ;Byte lesen
cmp.b D2,D4 ;ID-Byte gelesen?
beq v_use_spec
cmp.b D2,D5 ;SPEC-Byte gelesen?
beq v_use_spec
move.w D1,D6 ;temporären Zeiger basteln
addi.w #80,D6 ;eine Zeile weiter
cmpi.w #32000,D6 ;Zeilenüberlauf?
blo.s v_hilfe_1
subi.w #31999,D6 ;erste Zeile, eine Spalte weiter
cmpi.w #80,D6 ;schon ganz fertig?
beq.s v_as_is ;ja, also "as is" benutzen
v_hilfe_1: cmp.b 0(A0,D6.w),D2 ;gleiches Byte?
bne.s v_as_is ;nein, einzelnes Byte
addi.w #80,D6 ;Zeile weiter
cmpi.w #32000,D6 ;s.o
blo.s v_hilfe_2
cmpi.w #80,D6
beq.s v_as_is
subi.w #31999,D6 ;erste Zeile, eine Spalte weiter
v_hilfe_2: cmp.b 0(A0,D6.w),D2 ;nochmal gleiches Byte?
bne.s v_as_is ;2 gleiche Bytes lohnt noch nicht
cmp.b D2,D3 ;PACK-Byte gelesen?
beq.s v_use_pack ;ja, also ID-Byte-Codierung
bra.s v_use_spec ;nein, also SPEC-BYte-Codierung
v_as_is: move.b D2,0(A1,D0.w) ;Byte "as is" speichern
addq.w #1,D0 ;1 Byte gespeichert
addi.w #80,D1 ;Original-Bild eine Zeile tiefer
cmpi.w #32000,D1 ;Zeilenüberlauf?
blo.s v_lese ;nein, also weiterlesen
subi.w #31999,D1 ;Original-Bild-Zeiger korrigieren
cmpi.w #80,D1 ;bereits alles gelesen?
bne.s v_lese ;nein, also weiterlesen
rts ;sonst fertig...
;----------------------------------------------------------------------------
; PACK-Byte-Kompression vertikal
;----------------------------------------------------------------------------
v_use_pack: clr.b D2 ;Anzahl Pack-Byte
addi.w #80,D1 ;Original-Bild eine Zeile weiter
cmpi.w #32000,D1 ;Zeileüberlauf?
blo.s v_pack_1
subi.w #31999,D1 ;Offset korrigieren
v_pack_1: cmp.b 0(A0,D1.w),D3 ;immer noch PACK-Byte?
bne.s v_pack_fini
addi.b #1,D2 ;Anzahl erhöhen
addi.w #80,D1 ;Original-Bild weiter
cmpi.w #32000,D1 ;Zeilüberlauf testen...
blo.s v_pack_2 ;alles glatt gegangen
subi.w #31999,D1 ;Offset korrigieren
cmpi.w #80,D1 ;schon alles fertig?
bne.s v_pack_2 ;nein, also weiter
move.b D4,0(A1,D0.w) ; ID-Byte schreiben
move.b D2,1(A1,D0.w) ;und die Anzahl speichern
addq.w #2,D0 ;2 Bytes geschrieben
rts ;und fertig...
v_pack_2: cmpi.b #255,D2 ;max-Anzahl erreicht?
bne.s v_pack_1 ;nein, also weiter untersuchen
v_pack_fini: move.b D4,0(A1,D0.w) ;ID-Byte schreiben
move.b D2,1(A1,D0.w) ;Anzahl schreiben
addq.w #2,D0 ;zwei Bytes geschrieben
bra v_lese ;und weiter geht's...
;----------------------------------------------------------------------------
; SPEC-Byte-Kompression vertikal
;----------------------------------------------------------------------------
v_use_spec: clr.w D6 ;Anzahl SPEC-Byte
addi.w #80,D1 ;Original-Bild weiter
cmpi.w #32000,D1 ;Zeileüberlauf?
blo.s v_spec_1 ;nein, alles klaro
subi.w #31999,D1 ;Offsetkorrektur
cmpi.w #80,D1 ;schon alles fertig?
beq.s v_spec_fini_1 ;ja, also abbruch
v_spec_1: cmp.b 0(A0,D1.w),D2 ;immer noch Byte d?
bne.s v_spec_fini_2
addq.w #1,D6 ;Anzahl erhöhen
addi.w #80,D1 ;Original-Bild weiter
cmpi.w #32000,D1 ;Zeilenüberlauf?
blo.s v_spec_2 ;nein ->
subi.w #31999,D1 ;Offsetkorrektur
cmpi.w #80,D1 ;alles fertig?
bne.s v_spec_2 ;nein ->
v_spec_fini_1: move.b D5,0(A1,D0.w) ;SPEC-Byte schreiben
move.b D2,1(A1,D0.w) ;Byte d schreiben
move.b D6,2(A1,D0.w) ;Anzahl schreiben
addq.w #3,D0 ;3 Bytes geschrieben
rts ;und alles fertig
v_spec_2: cmpi.w #255,D6 ;max-Anzahl erreicht?
bne.s v_spec_1 ;nein, also weiter
v_spec_fini_2: move.b D5,0(A1,D0.w) ;SPEC-Byte schreiben
move.b D2,1(A1,D0.w) ;Byte d schreiben
move.b D6,2(A1,D0.w) ;Anzahl schreiben
addq.w #3,D0 ;drei Bytes geschrieben
bra v_lese ;und weiter gehts
END